/*
 * SMTPClientApp.java
 */
/*
 TO DO LIST
    -retr n ...DONE
    -retr all ...DONE
    -parse mail ...DONE
    -attatchments ...DONE
    -pop3 server
    -logica cliente
    -gui
    -mejorar diseño
    -pruebas

 */
package smtpclient;

import java.io.BufferedReader;
import java.io.File;

import java.io.IOException;

import java.io.InputStreamReader;
import java.io.PrintStream;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.jdesktop.application.Application;
import org.jdesktop.application.SingleFrameApplication;


/**
 * The main class of the application.
 */
public class SMTPClientApp extends SingleFrameApplication {

    static SMTPClientView eshta = null;
    
    /**
     * At startup create and show the main frame of the application.
     */
    @Override protected void startup() {
         
        show(new SMTPClientView(this));
    }

    /**
     * This method is to initialize the specified window by injecting resources.
     * Windows shown in our application come fully initialized from the GUI
     * builder, so this additional configuration is not needed.
     */
    @Override protected void configureWindow(java.awt.Window root) {
    }

    /**
     * A convenient static getter for the application instance.
     * @return the instance of SMTPClientApp
     */
    public static SMTPClientApp getApplication() {
        return Application.getInstance(SMTPClientApp.class);
    }
    public static void p(Object s){
        System.out.println(s);
    }

    

    public static void getAttatchment(String mail) throws IOException{

        String[] correo = mail.split("\n");
        String boundary = "";
        String filename = "";

        for(int i=3;i<correo.length-1;i++){
            if(correo[i].toLowerCase().contains("filename=")){
                filename = correo[i].substring(correo[i].indexOf("=")+2, correo[i].length()-1);
                break;
            }
        }
        for(int i=3;i<correo.length-1;i++){
            if(correo[i].toLowerCase().contains("boundary=")){
                boundary = correo[i].substring(correo[i].indexOf("=")+2,correo[i].length()-1);
                break;
            }
        }

        
        String[] partes = mail.split(boundary);
        String attatchment = "";
        int p = 0;
        for(int i = correo.length-1;0<i;i--){
            if(correo[i].contains(boundary)){
                p("ASDFASDFASDFASDFASDFASDFASDFASDFASDFASDF");
                i--;
                p++;
            }
            if(p==1){
                attatchment = correo[i]+ "\n" + attatchment;
            }
            if(p==2) break;
        }
        p("boundary: "+boundary);
        String[] at = attatchment.split("\n\n");
        p(attatchment);
        File file = new File(filename);
        Base64.decodeToFile(at[1], filename);
    }

    /**
     * Connects to a SMTP server using POP3 and retrieves all the emails' "From" and "Subject" fields
     * @param   server    name of the server.
     * @param   user username needed for authentication
     * @param   password password needed for authentincation
     * @return an array of Strings containing the sender and subject of each email.
     */
    public static String[][] retrieveAll(String server, String user, String password){
            String res = SMTPClientApp.connect(server,user, password,"LIST");
            return SMTPClientApp.retrieveSome(server, user, password,1,res.split("\n").length-2);
        }
     /**
     * Connects to a SMTP server using POP3 and retrieves all the emails' "From" and "Subject" fields from the "m"th to the "n"th
     * @param   server    name of the server.
     * @param   user username needed for authentication
     * @param   password password needed for authentincation
     * @param   m start index
     * @param   n end index
     * @return an array of Strings containing the sender and subject of each email.
     */
    public static String[][] retrieveSome(String server, String user, String password, int m, int n){
            String[][] response = null;
            String res = "";
            String mail = "";
        try {
            
            
            Socket s = new Socket(server, 110);
            PrintStream ps = new PrintStream(s.getOutputStream());
            BufferedReader b = new BufferedReader(new InputStreamReader(s.getInputStream()));
            p("Connection Successful!");
            
            res = b.readLine();
            ps.println("user " + user);
            p("user: " + user);
            res = b.readLine();
            p("user "+res);
            if (res.contains("OK")) {
                ps.println("pass " + password);
                res = b.readLine();
                p("asdf" + res);
                if (!res.contains("OK")) {
                    response = new String[1][1];
                    response[0][0] = res;
                    return response;
                }
            } else {
                response = new String[1][1];
                response[0][0] = res;
                return response;
            }
            response = new String[n-m+1][4];
            int e = 0;
            for(int j=m;j<=n;j++){

                ps.println("RETR "+ j);
                res = b.readLine()+"\n";
                p(res);
                mail = res;
                response[e][0] = Integer.toString(j);
                p("Respuestaa: \n" + mail);
                while(!res.equals(".")){
                    res = b.readLine();
                    if(res.toLowerCase().contains("date:")){
                        response[e][1] = res.substring(res.toLowerCase().indexOf("date:")+6);
                    }
                    if(res.toLowerCase().contains("from:")){
                        if(res.contains("<") && res.contains(">")){
                        response[e][2] = res.substring(res.toLowerCase().indexOf("<")+1, res.toLowerCase().indexOf(">"));
                        }else{
                        response[e][2] = res.substring(res.toLowerCase().indexOf("from:")+6);
                        }
                    }
                    if(res.toLowerCase().contains("subject:")){
                        response[e][3] = res.substring(res.toLowerCase().indexOf("subject:")+8);
                    }
                }
               
                mail = "";
                e++;
            }
           
            ps.println("quit");
            p(b.readLine());
            p("Exiting\n");
            ps.close();
            b.close();
            s.close();
            
        } catch (UnknownHostException ex) {
            Logger.getLogger(SMTPClientApp.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IOException ex) {
            Logger.getLogger(SMTPClientApp.class.getName()).log(Level.SEVERE, null, ex);
        }
        return response;
    }
     /**
     * receives a string containing a complete email and parses it returning only the body
     * @param   mail    the email without parsing
     * @return the parsed email
     */
    public static String parseMail(String mail){
        String boundary="|°|°|AE$";
        int start = 0;
        String charset = "";
        String return_value = "";
        String[] correo =mail.split("\n");
        for(int i=3;i<correo.length-1;i++){
            if(correo[i].toLowerCase().contains("boundary=\"-----")){
                boundary = correo[i].substring(correo[i].indexOf("----- =")+6,correo[i].length()-1);
            }
             if(correo[i].contains(boundary)){
                start++;
            }
            if(correo[i].toLowerCase().contains("charset=")){
                charset = correo[i].substring(correo[i].indexOf("=")+2,correo[i].length()-1);
                p(charset);
            }
            
            if(correo[i].equals("") && boundary.equals("|°|°|AE$")){
                start = 2;
            }
            
            if(start ==2){
                return_value += correo[i] +"\n";
            }
            
           p("Linea"+i+": "+correo[i]);
            
        }
        return  return_value;
        //return mail.substring(mail.indexOf(correo[1]),mail.length());
    }
    
       
    /**
     * Connects to a SMTP server using POP3
     * @param   server    name of the server.
     * @param   user username needed for authentication
     * @param   password password needed for authentincation
     * @param   command the command we want to execute
     * @return a String containing the server response to the command sent or the error received
     */
    public static String connect(String server,String user, String password, String command){
        String response = "";
        try {
            Socket s = new Socket(server, 110);
            PrintStream ps = new PrintStream(s.getOutputStream());
            BufferedReader b = new BufferedReader(new InputStreamReader(s.getInputStream()));
            p("Connection Successful!");
            response = b.readLine();
            ps.println("user " + user);
            response = b.readLine();
            if(response.contains("OK")){
                 ps.println("pass "+ password);
                 response = b.readLine();
                 if(!response.contains("OK")){
                    return response;
                 }
            }else{
                return response;
            }
            ps.println(command);
            Boolean condition = (
                    command.equalsIgnoreCase("list")? true :
                    command.equalsIgnoreCase("uidl")? true :
                    command.toLowerCase().contains("retr")? true :
                    command.toLowerCase().contains("top")? true :
                    false
            );
            if(condition){
                String res = b.readLine()+"\n";
                p(res);
                response = res;
                //p("Respuesta: \n" + response);
                while(!res.equals(".")){
                    res = b.readLine();
                    response += res+"\n";
                 //   p(response);
                }
            }else{
                response = b.readLine();
                p(response);
               // p("Respuesta: " + response);
            }
            ps.println("quit");
            p(b.readLine());
            p("Exiting\n");
            ps.close();
            b.close();
            s.close();
        } catch (UnknownHostException ex) {
            Logger.getLogger(SMTPClientApp.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IOException ex) {
            Logger.getLogger(SMTPClientApp.class.getName()).log(Level.SEVERE, null, ex);
        }
    return response;
    }

    /**
     * Main method launching the application.
     */
    public static void main(String[] args) {
       
        launch(SMTPClientApp.class, args);
        
    }
}
